<?php
/**
 * This file is part of workerman.
 *
 * Licensed under The MIT License
 * For full copyright and license information, please see the MIT-LICENSE.txt
 * Redistributions of files must retain the above copyright notice.
 *
 * @author walkor<walkor@workerman.net>
 * @copyright walkor<walkor@workerman.net>
 * @link http://www.workerman.net/
 * @license http://www.opensource.org/licenses/mit-license.php MIT License
 */

namespace app\worker;
/**
 * 推送主逻辑
 * 主要是处理 onMessage onClose
 */

use app\shop\model\chat\GroupUserModel;
use app\shop\model\user\ChatUserModel;
use app\shop\model\user\MessageModel;
use app\shop\model\user\UserModel;
use app\shop\service\user\UserService;
use GatewayWorker\Lib\Gateway;
use think\facade\Db;
use think\facade\Log;
use Workerman\Timer;

class Events
{
    // 使用TP框架
    public static function onWorkerStart()
    {
        $app = new Application;
        $app->initialize();
    }

    // 当有客户端连接时，将client_id返回，让mvc框架判断当前uid并执行绑定
    public static function onConnect($client_id)
    {
        // 打印文件位置：/runtime/easy_task/Std
//         dump('收到来自'.$client_id.'的连接');
//        Log::info('收到来自' . $client_id . '的连接。。。');
//        Log::save();
        Gateway::sendToClient($client_id, json_encode(array(
            'type' => 'init',
            'client_id' => $client_id,
            'content' => '连接成功'
        )));
    }

    /**
     * 有消息时
     * @param int $client_id
     * @param mixed $message
     */
    public static function onMessage($client_id, $message)
    {
        // 客户端传递的是json数据
        $message_data = json_decode($message, true);
//        Log::info('收到来自' . $client_id . '的消息，信息：'.$message);
//        Log::save();
        if (!$message_data) {
//            Log::error("clientID:" . $client_id . '消息格式错误');
//            Log::save();
            return;
        }
        $type = isset($message_data['type']) ? $message_data['type'] : '';
        if (!$type) {
//            Log::error("clientID:" . $client_id . '消息缺少type类型');
//            Log::save();
            return;
        }
        // 根据类型执行不同的业务
        switch ($type) {
            // 客户端回应服务端的心跳
            case 'pong':
                break;
            case 'ping':
                self::sendStatus($client_id);
                break;
            case 'bindUid':
                self::bindUid($client_id, $message_data);
                break;
            case 'call':
                break;
            case 'call_break':
                break;
        }
        return;
    }

    protected static function sendStatus($client_id)
    {
        $uid = $_SESSION['user_id'] ?? 0;
        $multiport = false;
        if ($uid) {
            $arr = Gateway::getClientIdByUid($uid);
            if (count($arr) > 1) {
                $multiport = true;
            }
        }
        Gateway::sendToClient($client_id, json_encode(array(
            'type' => 'pong',
            'multiport' => $multiport,
        )));

    }

    // 绑定用户
    protected static function bindUid($client_id, $msg)
    {
        try {
            $userId = self::verifyToken($msg);

            $_SESSION['user_id'] = $userId;

            Gateway::bindUid($client_id, $userId);

            // 查询用户所有的群组  加入群组
            $chatSignArr = GroupUserModel::where('user_id', $userId)->column('chat_sign');
            if (!$chatSignArr) {
                return true;
            }
            foreach ($chatSignArr as $chatSign) {
                Gateway::joinGroup($client_id, $chatSign);
            }

            // 回复消息 用户是否多端在线
            self::sendStatus($client_id);

            // 设置用户上线
//            $userInfo = UserModel::find($userId);
//            if ($userInfo->set_login_status == 2) {
//                $userInfo->login_status = 2;
//            } else {
//                $userInfo->login_status = 1;
//            }
//            $userInfo->save();


//            $data = [
//                'type' => 'isOnline',
//                'time' => time(),
//                'data' => ['id' => $userId, 'is_online' => 1, 'login_status' => $userInfo->login_status, 'route' => 'event/bindUid']
//            ];

            // 通知所有人用户上线
//            Gateway::sendToAll(json_encode($data));
            return true;
        } catch (\Exception $exception) {
            Log::error("clientID:".$client_id."，绑定用户错误:" . $exception->getMessage());
            Log::save();
            Gateway::sendToClient($client_id, $exception->getMessage());
//            self::closeClient($client_id);
            return false;
        }
    }

    /**
     * 验证用户身份
     * @param $messageData
     * @return mixed
     * @throws \Exception
     */
    public static function verifyToken($messageData)
    {
        $token = $messageData['token'] ?? '';
        if (!is_string($token)) {
            throw new \Exception('token不是字符串');
        }
        $tokenArr = explode('|', $token);
        if (count($tokenArr) != 2) {
            throw new \Exception('token错误');
        }
        if (!in_array($tokenArr[0], ['PC', 'APP'])) {
            throw new \Exception('token错误');
        }
        if ($tokenArr[0] == 'PC') {
            $tokenField = 'pc_token';
            $tokenValidField = 'pc_token_valid_time';
        } else {
            $tokenField = 'app_token';
            $tokenValidField = 'app_token_valid_time';
        }
        $userInfo = UserModel::where($tokenField, $token)->find();
        if (empty($userInfo)) {
            throw new \Exception('令牌错误');
        }
        if ($userInfo[$tokenValidField] <= time()) {
            throw new \Exception('令牌已失效');
        }
        $userId = $userInfo['user_id'];
        return $userId;
    }

    //断开连接
    protected static function closeClient($client_id)
    {
        $_SESSION['user_id'] = null;
        Gateway::closeClient($client_id);
    }

    /**
     * 当断开连接时
     * @param int $client_id
     */
    public static function onClose($client_id)
    {
//        Log::info("clientID:".$client_id."触发onclose事件" );
//        Log::save();
//        $user_id = $_SESSION['user_id'] ?? 0;
//        if ($user_id) {
//            $userInfo = UserModel::find($user_id);
//            // 设置用户离线
//            $userInfo->login_status = 0;
//            $userInfo->save();
//            Gateway::sendToAll(json_encode(array(
//                'type' => 'isOnline',
//                'time' => time(),
//                'data' => ['id' => $user_id, 'is_online' => 0, 'login_status' => 0, 'route' => 'onClose']
//            )));
//        }
//        self::closeClient($client_id);
    }
}
